const _ = require('lodash');
const async = require('async');
const commonService = require('./common');
const elancoService = require('./e-lanco');
const enums = require('../enums');

function forwardToApprover(req, res, callback) {
  const models = commonService.getModels();
  const { SysUser: userModel, WfRunFlowDetail: approvalDetailModel } = models;
  const formDetail = req.body;
  const instanceId = formDetail.id;
  const currentApprovalStep = formDetail.approvalStep;
  let taskList = [];
  const customMethodParams = formDetail.customMethodParams;
  const targetApprovalStep = customMethodParams.targetApprovalStep;
  const targetApproverEmployeeId = customMethodParams.forwardToOtherApprover;
  const forwordBeforeApprover = formDetail.forwordBeforeApprover;
  const deleteCurrentApprovalList = (next) => {
    approvalDetailModel.updateAll({ instanceId, approvalStep: targetApprovalStep }, { deleted: true }, error => next(error));
  };
  const getTargetApproverListByEmployeeId = (next) => {
    try {
      next(null, [targetApproverEmployeeId]);
    } catch (error) {
      throw error;
    }
  };
  const getTargetApproverList = (employeeIdList, next) => {
    commonService.getList(userModel, { where: { employeeId: { inq: employeeIdList } } }, next);
  };
  const getTargetApprovalList = (approverList, next) => {
    try {
      const approvalList = [];
      _.forEach(approverList, (approverItem) => {
                // 若只有er有forword，stepId默认为1，若是多个步骤都有，需要传递当前stepId
        const approvalItem = elancoService.createApprovalItem(formDetail.form, formDetail.flow, formDetail, 1, approverItem, targetApprovalStep);
        approvalList.push(approvalItem);
      });
      next(null, approvalList);
    } catch (error) {
      throw error;
    }
  };
  const createTargetApprovalList = (approvalList, next) => {
    approvalDetailModel.create(approvalList, next);
  };
  const handlEmailSendEvent = (approvalList, next) => {
    if (formDetail.flow.flowRun.isEmailSend) elancoService.handlForwordEmailSendEvent(formDetail.form, formDetail.flow, formDetail, forwordBeforeApprover, approvalList);
    next();
  };
  if (targetApprovalStep == currentApprovalStep) {
    taskList = taskList.concat([deleteCurrentApprovalList]);
    if (!_.isEmpty(targetApproverEmployeeId)) {
      taskList.push(getTargetApproverListByEmployeeId);
    }
    taskList = taskList.concat([getTargetApproverList, getTargetApprovalList, createTargetApprovalList, handlEmailSendEvent]);
  }
  async.waterfall(taskList, callback);
}

function searchUserListByQuery(req, res, callback) {
  const models = commonService.getModels();
  const { SysUser: userModel } = models;
  const customMethodParams = req.body.customMethodParams;
  const query = customMethodParams.query;
  userModel.findUserListByQuery(query, callback);
}

function manpowerRequisitionGetHiringManager(req, res, callback) {
  const models = commonService.getModels();
  const { SysUser: userModel } = models;
  const data = req.body;
  const customMethodParams = data.customMethodParams;
  const hiringManager = customMethodParams.hiringManager;
  const result = {
    isSales: false,
    businessNode1: '',
    businessNode2: '',
    businessNode3: '',
    businessNode4: '',
  };
  const getHierarchy = (next) => {
    userModel.findHierarchyByEmployeeId(hiringManager.employeeId, (error, hierarchy) => {
      if (!_.isEmpty(hierarchy)) {
        if (_.toString(hierarchy.BU.SalesPosition.Code) == 3 ||
                    _.toString(hierarchy.BU.SalesPosition.Code) == 6 ||
                    _.toString(hierarchy.BU.SalesPosition.Code) == 7 ||
                    _.toString(hierarchy.BU.SalesPosition.Code) == 8 ||
                    _.toString(hierarchy.BU.SalesPosition.Code) == 9) {
          result.isSales = true;
        }
      }
      next(error);
    });
  };
  const getBusinessNode = (next) => {
    userModel.findUserByEmployeeId(hiringManager.employeeId, (error, user) => {
      if (!_.isEmpty(user)) {
        result.businessNode1 = _.toString(user.Bus_Node_1_Title);
        result.businessNode2 = _.toString(user.Bus_Node_2_Title);
        result.businessNode3 = _.toString(user.Bus_Node_3_Title);
        result.businessNode4 = _.toString(user.Bus_Node_4_Title);
      }
      next(error);
    });
  };
  async.waterfall([getHierarchy, getBusinessNode], (error) => {
    callback(error, result);
  });
}

function manpowerRequisitionRevocationForm(req, res, callback) {
  const models = commonService.getModels();
  const { WfRunInstance: formDetailModel, WfRunFlowDetail: approvalDetailModel } = models;
  const formDetail = req.body;
  const approvalListEmailNeed = formDetail.approvalListEmailNeed;
  const id = formDetail.id;
  const employeeId = commonService.getEmployeeId();
  const updateFormDetail = (next) => {
    formDetailModel.upsert({
      id,
      approvalStep: 5,
      formDetail: formDetail.formDetail,
      formStatus: enums.formStatus.rejected4,
    }, error => next(error));
  };
  const updateApprovalDetail = (next) => {
    approvalDetailModel.upsertWithWhere({
      instanceId: id,
      approvalStep: formDetail.approvalStep,
      approverEmployeeId: employeeId,
      deleted: false,
    }, {
      approvalStatus: enums.approvalStatus.reject,
    }, next);
  };
  const handlEmailSendEvent = (approvalList, next) => {
    if (formDetail.flow.flowRun.isEmailSend) elancoService.handlRevocationFormEmailSendEvent(formDetail.form, formDetail.flow, formDetail, [approvalList], approvalListEmailNeed);
    next();
  };
  async.waterfall([updateFormDetail, updateApprovalDetail, handlEmailSendEvent], callback);
}

module.exports = {
  forwardToApprover,
  searchUserListByQuery,
  manpowerRequisitionGetHiringManager,
  manpowerRequisitionRevocationForm,
};
